package com.aiden.app.common.base

import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Process
import cn.jpush.android.api.JPushInterface
import com.aiden.app.common.BuildConfig
import com.aiden.app.common.constant.ConfigConstants
import com.aiden.app.common.constant.Constants
import com.aiden.app.common.constant.PrefConstants
import com.aiden.app.common.extension.getInt
import com.aiden.app.common.extension.getString
import com.aiden.app.common.extension.putString
import com.aiden.app.common.http.NetWork
import com.aiden.app.common.http.adapter.LiveDataAdapterFactory
import com.aiden.app.common.http.config.HttpGlobalConfig
import com.aiden.app.common.http.converter.GsonConverterFactory
import com.aiden.app.common.http.cookie.CookieConfig
import com.aiden.app.common.http.interceptor.HttpCacheInterceptor
import com.aiden.app.common.http.interceptor.HttpHeaderInterceptor
import com.aiden.app.common.service.TBSIntentService
import com.aiden.app.common.util.DeviceUtil
import com.aiden.app.common.util.DeviceUuidFactory
import com.aiden.app.common.util.LogUtils
import com.aiden.app.common.util.SystemUtil
import com.aiden.app.common.widget.refresh.NormalFooter
import com.aiden.app.common.widget.refresh.NormalHeader
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.google.gson.Gson
import com.huawei.android.hms.agent.HMSAgent
import com.meizu.cloud.pushsdk.PushManager
import com.scwang.smartrefresh.layout.SmartRefreshLayout
import com.scwang.smartrefresh.layout.api.*
import com.tencent.bugly.Bugly
import com.tencent.bugly.crashreport.CrashReport
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.tencent.tauth.Tencent
import com.xiaomi.channel.commonutils.logger.LoggerInterface
import com.xiaomi.mipush.sdk.Logger
import com.xiaomi.mipush.sdk.MiPushClient
import okhttp3.ConnectionPool
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.util.concurrent.TimeUnit

open class BaseApplication : Application() {

    companion object {
        lateinit var INSTANCE: BaseApplication
            private set
    }

    init {
        SmartRefreshLayout.setDefaultRefreshInitializer(object : DefaultRefreshInitializer {
            override fun initialize(context: Context, layout: RefreshLayout) {
                layout.setEnableAutoLoadMore(true)
                layout.setDragRate(0.8f)
            }
        })
        // 设置全局下拉刷新
        SmartRefreshLayout.setDefaultRefreshHeaderCreator(object : DefaultRefreshHeaderCreator {
            override fun createRefreshHeader(context: Context, layout: RefreshLayout): RefreshHeader {
                return NormalHeader(context)
            }
        })
        // 设置全局上拉加载
        SmartRefreshLayout.setDefaultRefreshFooterCreator(object : DefaultRefreshFooterCreator {
            override fun createRefreshFooter(context: Context, layout: RefreshLayout): RefreshFooter {
                return NormalFooter(context)
            }
        })
    }

    private val TAG = "Application"
    private lateinit var iwxapi: IWXAPI
    private lateinit var tencent: Tencent
    var mSavedHostIndex: Int = 0
    lateinit var userId: String
    var device = Constants.OTHER
    var token = ""

    override fun onCreate() {
        super.onCreate()
//        checkSignature()
        INSTANCE = this

        initUserId()

//        object : Thread() {
//            override fun run() {
//                super.run()
//                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)
//                initWechat()
//                initX5()
//                initQQ()
//                initBugly()
//            }
//        }.start()
//        initPush()
    }

    fun getWXApi(): IWXAPI {
        return iwxapi
    }

    fun getTencent(): Tencent {
        return tencent
    }

    fun initNetwork(baseUrl: String) {
        NetWork.INSTANCE.apply {
            readTimeout(HttpGlobalConfig.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            writeTimeout(HttpGlobalConfig.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
            connectTimeout(HttpGlobalConfig.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)

            connectionPool(ConnectionPool(HttpGlobalConfig.DEFAULT_MAX_IDLE_CONNECTIONS, HttpGlobalConfig.DEFAULT_KEEP_ALIVE_DURATION, TimeUnit.SECONDS))

            interceptor(HttpHeaderInterceptor(params = HttpGlobalConfig.params(), headers = makeHeaders()))

            val loggingInterceptor = HttpLoggingInterceptor { message ->
                LogUtils.d(HttpGlobalConfig.HTTP_LOG_TAG, message)
            }
            loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
            interceptor(loggingInterceptor)

            networkInterceptor(HttpCacheInterceptor(HttpGlobalConfig.CACHE_MAX_AGE, this@BaseApplication))
            cache(File(cacheDir, "cache"), HttpGlobalConfig.CACHE_SIZE)

            convertFactory(GsonConverterFactory(Gson()))
            callAdapterFactory(LiveDataAdapterFactory())
        }.let {
            it.cookieJar(CookieConfig(this))
            it
        }.build(baseUrl)
    }

    private fun initX5() {
        TBSIntentService.enqueueWork(this, Intent())
    }

    private fun initWechat() {
        iwxapi = WXAPIFactory.createWXAPI(this, ConfigConstants.WX_APP_ID, BuildConfig.DEBUG)
        iwxapi.registerApp(ConfigConstants.WX_APP_ID) // 将应用的 appID 注册到微信
    }

    private fun initQQ() {
        tencent = Tencent.createInstance(ConfigConstants.QQ_APP_ID, applicationContext)
    }

    private fun initBugly() {
        CrashReport.initCrashReport(this, "bb8d4a6ce9", false)
        Bugly.init(this, "bb8d4a6ce9", false)
    }

    private fun initPush() {
        when (DeviceUtil.getManufacturer().toLowerCase()) {
            Constants.XIAOMI -> {
                // 初始化小米推送SDK
                LogUtils.i(TAG, "初始化小米推送SDK")
                device = Constants.XIAOMI
                initMIPush()
            }
            Constants.HUAWEI -> {
                // 初始化华为推送SDK
                LogUtils.i(TAG, "初始化华为推送SDK")
                device = Constants.HUAWEI
                initHuaweiPush()
            }
            Constants.MEIZU -> {
                // 初始化魅族推送SDK
                LogUtils.i(TAG, "初始化魅族推送SDK")
                device = Constants.MEIZU
                initMeizuPush()
            }
            else -> {
                // 初始化极光推送SDK
                device = Constants.OTHER
                JPushInterface.setDebugMode(BuildConfig.DEBUG)
                JPushInterface.init(applicationContext)
                if (JPushInterface.isPushStopped(this)) {
                    JPushInterface.resumePush(this)
                }
            }
        }
    }

    /**
     * 初始化小米推送
     */
    private fun initMIPush() {
        if (shouldInit()) {
            LogUtils.d(TAG, "初始化小米推送")
            MiPushClient.registerPush(this, ConfigConstants.MIPUSH_APP_ID, ConfigConstants.MIPUSH_APP_KEY)
        }
        val logger = object : LoggerInterface {
            override fun setTag(p0: String?) {

            }

            override fun log(p0: String?) {
                LogUtils.d("MIPush", p0!!)
            }

            override fun log(p0: String?, p1: Throwable?) {
                LogUtils.d("MIPush", p0!!, p1!!)
            }

        }
        Logger.setLogger(this, logger)
        stopJPush()
    }

    private fun initHuaweiPush() {
        HMSAgent.init(this)
        stopJPush()
    }

    private fun initMeizuPush() {
        PushManager.register(this)
        stopJPush()
    }

    private fun stopJPush() {
        if (!JPushInterface.isPushStopped(this)) {
            JPushInterface.stopPush(this)
        }
    }

    private fun initUserId() {
        userId = getString(PrefConstants.USER_ID)
        token = getString(PrefConstants.Token)
    }

    fun putUserId(userId: String) {
        this.userId = userId
        putString(PrefConstants.USER_ID, userId)
    }

    fun putToken(token: String) {
        this.token = token
        putString(PrefConstants.Token, token)
    }

    /**
     * 检查签名hash值，防止二次打包
     */
    private fun checkSignature() {
        val sign = getSignature()
        if (669693696 != Math.abs(sign)) {
            android.os.Process.killProcess(android.os.Process.myPid())
        }
    }

    private fun getSignature(): Int {
        val pm = packageManager
        val pi: PackageInfo
        val sb = StringBuilder()

        try {
            pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
            val signatures = pi.signatures
            for (signature in signatures) {
                sb.append(signature.toCharsString())
            }
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }

        return sb.toString().hashCode()
    }

    private fun makeHeaders(): Map<String, String> {
        val headers = HashMap<String, String>()
        headers[ConfigConstants.HEADER_MAC_NO] = DeviceUtil.getMac()
        headers[ConfigConstants.HEADER_INTERFACE_VERSION] = BuildConfig.INTERFACE_VERSION
        headers[ConfigConstants.HEADER_MOBILE_MODEL] = DeviceUtil.getModel()
        headers[ConfigConstants.HEADER_REQUEST_SOURCE] = "2"
        headers[ConfigConstants.HEADER_APP_VERSION] = SystemUtil.getAppVersion(this)
        headers[ConfigConstants.HEADER_MOBILE_OS_VERSION] = DeviceUtil.getOSVersion()
        headers[ConfigConstants.HEADER_DEVICE_ID] = DeviceUuidFactory(this).deviceId
        return headers
    }

    private fun shouldInit(): Boolean {
        val am = this.applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val processInfos = am.runningAppProcesses
        val mainProcessName = packageName
        val myPid = Process.myPid()
        for (info in processInfos) {
            if (info.pid == myPid && mainProcessName.equals(info.processName)) {
                return true
            }
        }
        return false
    }
}